#include "stdafx.h"
#include "mainrun.h"

CMainRunImpl::CMainRunImpl(void)
{
}
CMainRunImpl::~CMainRunImpl(void)
{
    logi("CMainRun::~CMainRun");
}
HRESULT CMainRunImpl::CreateObject(REFCLSID rid, IBase** pIObjectRun, SafePStringConstPtr path, SafeStringConstPtr code)
{
    HRESULT hr = S_OK;

    rc_error(path != NULL, E_FAIL);
    rc_error(path->len != 0, E_FAIL);
    rc_error(path->ptr != NULL, E_FAIL);

    rc_error(code != NULL, E_FAIL);
    rc_error(code->len != 0, E_FAIL);
    rc_error(code->ptr != NULL, E_FAIL);

    SYNC_OBJ(&m_lock)

    rc_error(m_obj.count(rid) == 0, E_FAIL);

    CObjectRunImpl* p = ALLOC_NEW CObjectRunImpl();
    rc_error(p != NULL, E_OUTOFMEMORY);

    ObjectRunItem& Item = m_obj[rid];

    hr = p->QueryInterface(IID_IObjectRun, (void**)&Item.m_ptr);
    rc_error(hr == S_OK, E_FAIL);

    hr = Item.m_ptr->Clear();
    rc_error(hr == S_OK, E_FAIL);

    hr = Item.m_ptr->SetClsid(rid);
    rc_error(hr == S_OK, E_FAIL);

    hr = Item.m_ptr->SetPath(path);
    rc_error(hr == S_OK, E_FAIL);

    hr = Item.m_ptr->LoadConf(code);
    rc_error(hr == S_OK, E_FAIL);

    hr = Item.m_ptr->QueryInterface(IID_IObjectRun, (void**)pIObjectRun);
    rc_error(hr == S_OK, E_FAIL);

    hr = Item.m_ptr->SetMainRun(this);
    rc_error(hr == S_OK, E_FAIL);

    return S_OK;
}
int CMainRunImpl::IsObjectExist(REFCLSID rid)
{
    SYNC_OBJ(&m_lock)
    ObjectStructIterator it = m_obj.find(rid);
    rc_error(m_obj.end() != it, S_ERROR);
    return S_SUCCESS;
}
HRESULT CMainRunImpl::GetObjectRun(REFCLSID rid, IBase** pIObjectRun)
{
    SYNC_OBJ(&m_lock)

    ObjectStructIterator it = m_obj.find(rid);
    rc_error(m_obj.end() != it, S_ERROR);

    return it->second.m_ptr->QueryInterface(IID_IObjectRun, (void**)pIObjectRun);
}
HRESULT CMainRunImpl::GetObject(REFCLSID rid, REFCLSID clsid, REFCLSID iid, IBase** ppunk)
{
    HRESULT hr = S_OK;

    SYNC_OBJ(&m_lock)

    ObjectStructIterator it = m_obj.find(rid);
    rc_error(m_obj.end() != it, S_ERROR);

    ObjectRunPtr objectrunptr;
    hr = it->second.m_ptr->QueryInterface(IID_IObjectRun, (void**)&objectrunptr);
    rc_error(hr == S_OK, E_FAIL);

    _lComPtr<IRot> pIRot;
    hr = objectrunptr->GetRotPlugin((IBase**)&pIRot);
    rc_error(hr == S_OK, E_FAIL);

    return pIRot->GetObject(clsid, iid, ppunk);
}
HRESULT CMainRunImpl::FreeObject(REFCLSID id, UINT exit)
{
    SYNC_OBJ(&m_lock)
    return S_OK;
}
HRESULT CMainRunImpl::Free(UINT exit)
{
    SYNC_OBJ(&m_lock)
    m_obj.clear();
    return S_OK;
}
HRESULT
CMainRunImpl::SendMsg(REFCLSID rid, REFCLSID gn, REFCLSID sn, REFCLSID tn, UINT msg, IBase* inmsg, IBase** outmsg)
{
    HRESULT hr = S_OK;
    ObjectRunPtr pIObjectRun;

    hr = this->GetObjectRun(rid, (IBase**)&pIObjectRun);
    rc_error(hr == S_OK, E_FAIL);

    MsgPluginPtr pIMsgRun;

    hr = pIObjectRun->GetMsgPlugin((IBase**)&pIMsgRun);
    rc_error(hr == S_OK, E_FAIL);

    return pIMsgRun->OnMsgSend(sn, tn, msg, inmsg, outmsg);
}
HRESULT
CMainRunImpl::SendBroadcastMsg(REFCLSID gn, REFCLSID sn, REFCLSID tn, UINT msg, IBase* inmsg)
{
    SYNC_OBJ(&m_lock)

    ObjectStructIterator it = m_obj.begin();
    while (it != m_obj.end()) {
        HRESULT hr = S_OK;

        MsgPluginPtr pIMsgRun;

        hr = it->second.m_ptr->GetMsgPlugin((IBase**)&pIMsgRun);
        rc_error_continue(hr == S_OK);

        hr = pIMsgRun->OnMsgSend(sn, tn, msg, inmsg, NULL);

        it++;
    }
    return S_OK;
}
